#include "StdAfx.h"
#include "IniData.h"

bool CIniData::Load(CBaseReader& fr)
{
  int     section = -1;
  CString line;
  CString comments;

  while (fr.ReadLine(line))
  {
    if (line.IsEmpty())
      continue;

    line.Trim();

    if (line[0] == TEXT('['))
    {
      int pos = line.ReverseFind(TEXT(']'));
      CString sSection = line.Mid(1, pos - 1);
      m_Sections.push_back(sSection);
      section++;
    }
    else if (line[0] == TEXT(';') || (line.GetLength() > 1 && line[0] == TEXT('/') && line[1] == TEXT('/')))
    {
      if (!comments.IsEmpty())
        comments += CBaseWriter::eol;
      comments += line;
    }
    else
    {
      int pos = line.Find(TEXT('='));
      if (pos >= 0)
      {
        CString name = line.Left(pos);
        CString value = line.Mid(pos + 1);
        name.Trim();
        value.Trim();
        CIniItem* pItem = new CIniItem();
        if (pItem)
        {
          pItem->SetSection(section);
          pItem->SetComments(comments);
          pItem->SetName(name);
          pItem->SetValue(value);
          m_Items.push_back(pItem);
        }
      }
      comments.Empty();
    }
  }

  return m_Items.size() > 0;
}

bool CIniData::Save(CBaseWriter& fw) const
{
  int section = -1;

  for (CItemList::const_iterator iter = m_Items.begin(); iter != m_Items.end(); iter++)
  {
    CIniItem* pItem = *iter;
    if (!pItem)
      continue;

    if (pItem->GetSection() != section)
    {
      section = pItem->GetSection();
      if (section >= 0 && section < (int)m_Sections.size())
        fw.WriteSection(m_Sections[section]);
    }

    bool res = fw.WriteLine(pItem->GetComments()) &&
           fw.WritePair(pItem->GetName(), pItem->GetValue(), TEXT('=')) &&
           fw.WriteLine(CBaseWriter::eol);
    if (!res)
      return false;
  }

  return true;
}

void CIniData::Clear()
{
  m_Sections.clear();

  for (CItemList::iterator iter = m_Items.begin(); iter != m_Items.end(); iter++)
  {
    CIniItem* pItem = *iter;
    if (pItem)
      delete pItem;
  }
  m_Items.clear();
}

CIniItem* CIniData::FindItem(const CString& name)
{
  for (CItemList::iterator iter = m_Items.begin(); iter != m_Items.end(); iter++)
  {
    CIniItem* pItem = *iter;
    if (pItem && name.CompareNoCase(pItem->GetName()) == 0)
      return pItem;
  }
  return NULL;
}